#!/bin/bash


# Download stuffs
if [ "$1" == "download_code" ]; then

  # Coreboot
  if [ ! -d ./coreboot ]; then
    printf "Downloading Coreboot\n"
    git clone --recursive http://review.coreboot.org/coreboot.git ./coreboot
  else
    printf "Coreboot repository is already present\n"
  fi

  # GRUB
  if [ ! -d ./grub ]; then
    printf "Downloading GRUB\n"
    git clone git://git.savannah.gnu.org/grub.git ./grub
    
    # Checkout this specific version
    cd ./grub
    git checkout "tags/2.02"
    cd ..
  else
    printf "GRUB repository is already present\n"
  fi

  # me_cleaner
  if [ ! -d ./me_cleaner ]; then
    printf "Downloading me_cleaner\n"
    git clone https://github.com/corna/me_cleaner.git ./me_cleaner
  else
    printf "me_cleaner repository is already present\n"
  fi


# Build Coreboot Utilities
elif [ "$1" == "build_utils" ]; then

  if [ ! -d "coreboot/.git" ]; then
    printf "No Coreboot repository found in coreboot/\nDownload the code first\n"
    exit 1
  fi

  # Build ifdtool for stock BIOS splitting
  cd coreboot/util/ifdtool
  make -j${nproc}
  cd ../../../
  
  # Build cbfstool for managing Coreboot's filesystem
  cd coreboot/util/cbfstool
  make -j${nproc}
  cd ../../../
  

# Split the stock rom and organize the parts
elif [ "$1" == "split_bios" ]; then

  if [ ! -f "binaries/bios.bin" ]; then
    printf "No stock bios (bios.bin) file found in binaries/\n"
    exit 1
  fi

  if [ ! -f "coreboot/util/ifdtool/ifdtool" ]; then
    printf "No ifdtool present, build the Coreboot utils first\n"
    exit 1
  fi

  cd binaries/
  ../coreboot/util/ifdtool/ifdtool -x bios.bin
  mv flashregion_0_flashdescriptor.bin descriptor.bin
  rm flashregion_1_bios.bin
  mv flashregion_2_intel_me.bin me.bin
  mv flashregion_3_gbe.bin gbe.bin
  cd ..
  

# Neuter Intel ME
elif [ "$1" == "neuter_me" ]; then

  if [ ! -f "binaries/me.bin" ]; then
    printf "No Intel ME (me.bin) binary found in binaries/\n"
    exit 1
  fi

  cp binaries/me.bin binaries/me_neutered.bin
  python3 me_cleaner/me_cleaner.py binaries/me_neutered.bin


# Prepare Coreboot for compilation
elif [ "$1" == "pre_build_coreboot" ]; then

  # Copy the config
  cp "config/coreboot.config" coreboot/.config
  
  # Goto the Coreboot directory
  cd coreboot
  
  # Build toolchain
  make crossgcc-i386 CPUS=${nproc} -b
  
  # Build IASL
  make -j${nproc} iasl
  
  # Get back
  cd ..


# Build Coreboot
elif [ "$1" == "build_coreboot" ]; then

  # Goto the coreboot directory
  cd coreboot

  # Clean last build
  make clean
  rm ../out/coreboot.rom

  # Just make
  make -j${nproc} || make -j${nproc}

  # Exit if failed
  if [ $? -ne 0 ]; then
    printf "Failed to build Coreboot.\nExiting...\n"
    exit 1
  fi

  # Get back
  cd ..

  # Copy the resulting binary to a more accessible folder
  if [ ! -d out/ ]; then mkdir out/; fi
  mv coreboot/build/coreboot.rom out/coreboot.rom


# Build GRUB
elif [ "$1" == "build_grub" ]; then

  # Check if the GRUB code is present
  if [ ! -d "grub/.git" ]; then
    printf "No GRUB repository found in grub/\nDownload the code first\n"
    exit 1
  fi

  # Change title just for goofs
  sed -i "s/_(\"GNU GRUB  version %s\"), PACKAGE_VERSION/\"COREBOOT\"/g" grub/grub-core/normal/main.c

  # Copy the config
  cp "config/grub.config" "grub/.config"

  # Clean last build
  cd grub
  make clean
  cd ..

  # Build GRUB
  cd grub
  ./autogen.sh
  ./configure --with-platform=coreboot --disable-werror
  make -j${nproc}
  cd ..


# Assemble the GRUB payload
elif [ "$1" == "assemble_grub" ]; then

  printf "Assembling the GRUB payload\n"
  
  # Load modules config
  source "config/grub_modules.conf"
  
  # Assemble GRUB
  grub/grub-mkstandalone \
    --grub-mkimage="grub/grub-mkimage" \
    -O i386-coreboot \
    -o "out/grub.elf" \
    -d "grub/grub-core/" \
    --fonts= --themes= --locales=  \
    --modules="${grub_modules}" \
    --install-modules="${grub_install_modules}" \
    /boot/grub/grub.cfg="config/grub_memdisk.cfg" \
    /dejavusansmono.pf2="misc/dejavusansmono_24bold.pf2" \
    /boot/grub/layouts/usqwerty.gkb="misc/usqwerty.gkb"


# Configure SeaBIOS to chainload with GRUB
elif [ "$1" == "config_seabios" ]; then

  printf "Configure SeaBIOS\n"

  if [ ! -f "out/coreboot.rom" ]; then
    printf "No Coreboot image found.\nBuild Coreboot first.\n"
    exit 1
  fi

  # Set GRUB as the default boot device
  printf "/rom@img/grub2\n" > "out/bootorder"
  coreboot/util/cbfstool/cbfstool "out/coreboot.rom" add -f "out/bootorder" -n bootorder -t raw
  rm -f "out/bootorder"

  # Hide SeaBIOS
  coreboot/util/cbfstool/cbfstool "out/coreboot.rom" add-int -i 0 -n etc/show-boot-menu

  # Don't load anything else
  coreboot/util/cbfstool/cbfstool "out/coreboot.rom" add-int -i 0 -n etc/pci-optionrom-exec

  # Print the contents of the CBFS volume
  coreboot/util/cbfstool/cbfstool "out/coreboot.rom" print


# Install and config GRUB
elif [ "$1" == "install_grub" ]; then

  printf "Install GRUB in the CBFS volume\n"

  if [ ! -f "out/coreboot.rom" ]; then
    printf "No Coreboot image found.\nBuild Coreboot first.\n"
    exit 1
  fi

  # Compress and add GRUB payload
  coreboot/util/cbfstool/cbfstool "out/coreboot.rom" add-payload -c lzma -f "out/grub.elf" -n img/grub2 && rm "out/grub.elf"

  # Add grub.cfg
  coreboot/util/cbfstool/cbfstool "out/coreboot.rom" add -f "config/grub.cfg" -n grub.cfg -t raw

  # Print the contents of the CBFS volume
  coreboot/util/cbfstool/cbfstool "out/coreboot.rom" print


# Flashing activities
elif [ "$1" == "flash" ]; then
  
  # Define which programmer to use
  case "$3" in
  
  # Internal
  "internal" )
    programmer="internal:laptop=force_I_want_a_brick"
  ;;
    
  # Raspberry Pi
  "rpi" )
    programmer="linux_spi:dev=/dev/spidev0.0"
  ;;
  
  # Arduino Boards with Xu2 USB chips
  "u2" )
    programmer="serprog:dev=/dev/ttyACM0:115200"
  ;;

  # Arduino Boards with FTDI USB chips
  "ftdi" )
    programmer="serprog:dev=/dev/ttyUSB0:2000000"
  ;;
  
  # Exit if no programmer is specified
  * )
    printf "You must specify the programmer\n"
    exit 1
  ;;
  
  esac
  
  # Write to the flash chip
  if [ "$2" == "write" ]; then
  
    # Exit if Coreboot hasn't been successfully compiled yet
    if [ ! -f "out/coreboot.rom" ]; then
      printf "Build Coreboot first\n"
      exit 1
    fi
    
    flashrom -p $programmer -w "out/coreboot.rom"

  # Do consecutive reads of the flash chip and compare them
  elif [ "$2" == "read" ]; then
    mkdir binaries/reads
    
    for i in {1..5}; do
      flashrom -p $programmer -r "binaries/reads/bios$i.bin"
      md5sum "binaries/reads/*.bin"
    done
    
  # Check if the flash chip is detected
  elif [ "$2" == "check" ]; then
    flashrom -p $programmer
  fi

# Exit if no operation is specified
else
  printf "No operation specified\n"
  exit 1
  
fi
